package com.niknik.woody.utils.wunit.junit.rule;

import com.niknik.woody.utils.wunit.junit.runner.WUnitContext;
import org.junit.rules.ExternalResource;
import org.mockito.InOrder;
import org.mockito.Mockito;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;

public class MockKeeperRule
    extends ExternalResource {

  private WUnitContext context;

  private List<Object> mocks = new LinkedList<Object>();
  private InOrder inOrder = null;

  public MockKeeperRule(WUnitContext context) {
    this.context = context;
  }

  public <T> T verify(T mock) {
    return inOrder().verify(mock);
  }

  @Override
  protected void after() {
    super.after();
    context.getExCollector().checkSucceeds(new Callable<Object>() {

      @Override
      public Object call()
          throws Exception {
        inOrder().verifyNoMoreInteractions();
        return true;
      }
    });
  }

  private InOrder inOrder() {
    return inOrder == null
        ? inOrder = Mockito.inOrder(mocks.toArray())
        : inOrder;
  }

  public void register(Object mock) {
    mocks.add(mock);
  }
}